package com.cqrt.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cqrt.constant.RTErrorCodeEnum;
import com.cqrt.constant.RTPlmConstant;
import com.cqrt.dto.OAProjectJobDTO;
import com.cqrt.dto.ProjectPlanChangeDTO;
import com.cqrt.dto.RTPlanUpdateDTO;
import com.cqrt.entity.PlanTime;
import com.cqrt.mapper.RTProjectMapper;
import com.cqrt.mapper.RTTaskMapper;
import com.cqrt.service.ProjectChangeService;
import com.cqrt.service.RTOaChangeInfoService;
import com.cqrt.util.WorkdayCalculator;
import com.cqrt.vo.MIBAVO;
import com.cqrt.vo.TyJobVO;
import com.github.pagehelper.PageInfo;
import com.hustcad.plm.rpm.model.dto.active.PlusTaskDTO;
import com.hustcad.plm.rpm.model.dto.active.PlusTaskSaveDTO;
import com.hustcad.plm.rpm.model.entity.admin.TyppmProject;
import com.hustcad.plm.rpm.model.entity.change.TyppmChangeInfo;
import com.hustcad.plm.rpm.model.entity.plan.TyppmPlanActive;
import com.hustcad.plm.rpm.model.vo.change.ActiveUpdateVO;
import com.hustcad.plm.rpm.model.vo.change.CreateChangeInfoRequestVO;
import com.hustcad.plm.rpm.model.vo.change.PlanChangeInfoVO;
import com.hustcad.plm.rpm.model.vo.change.TyppmChangeInfoVO;
import com.hustcad.plm.rpm.project.service.TyppmProjectService;
import com.hustcad.plm.rpm.service.change.TyppmChangeInfoService;
import com.hustcad.plm.rpm.service.plan.TyppmGanttChartService;
import com.hustcad.plm.rpm.service.plan.TyppmPlanActiveService;
import com.hustcad.plm.rpm.util.RedisUtils;
import com.lark.oapi.okhttp.MediaType;
import com.lark.oapi.okhttp.OkHttpClient;
import com.lark.oapi.okhttp.Request;
import com.lark.oapi.okhttp.RequestBody;
import com.lark.oapi.okhttp.Response;
import com.ty.basic.constant.TableTypeConstrant;
import com.ty.basic.entity.org.UserDO;
import com.ty.basic.service.snow.SnowflakeIdComponent;
import com.ty.basic.session.TyAccountContext;
import lombok.extern.slf4j.Slf4j;
import oracle.sql.TIMESTAMP;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigInteger;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RTOaChangeInfoServiceImpl implements RTOaChangeInfoService {

    @Value("${oa.token.url}")
    private String oaTokenUrl;

    @Value("${oa.changeInfo.url}")
    private String url;

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private RTTaskMapper rtTaskMapper;
    @Resource
    private TyppmProjectService typpmProjectService;
    @Resource
    private ProjectChangeService projectChangeService;
    @Resource
    private TyppmPlanActiveService typpmPlanActiveService;
    @Resource
    private TyppmGanttChartService ganttChartService;
    @Resource
    private RTProjectMapper rtProjectMapper;
    @Autowired
    private SnowflakeIdComponent snowflakeIdComponent;

    private static final List<String> RISK_TYPE_LIST = Arrays.asList("UNAVAILABLE", "Very low", "Low", "Medium", "High", "Very high");

    @Override
    public String getOaToken() {
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        Request request = new Request.Builder()
                .url(oaTokenUrl)
                .method("GET", null)
                .addHeader("Content-Type", "application/json")
                //.addHeader("Cookie", "JSESSIONID=C1E23D9957B62C4752F849414632F2CF")
                .build();
        try {
            Response response = client.newCall(request).execute();
            assert response.body() != null;
            String body = response.body().string();
            JSONObject jsonObject = JSONObject.parseObject(body);
            return jsonObject.getString("id");
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    @Override
    public String changePlan(String projectId,String type) {

        TyppmProject typpmProject = typpmProjectService.selectOneByOID(projectId);
        if (Objects.isNull(typpmProject)){
            throw new RuntimeException("项目实体不存在");
        }
        JSONObject data = new JSONObject();
        UserDO user = TyAccountContext.getUser();
        JSONObject jo = new JSONObject();
        if (type.equals("项目暂停")){
            updateExecutionStatus(projectId,type);
            jo.put("field0012","1");
        }else if (type.equals("项目恢复")){

            updateExecutionStatus(projectId,type);
            jo.put("field0060","1");
            JSONArray jsonArray=new JSONArray();
            String rootPlanId =rtTaskMapper.selectPlanIdByProjectId(projectId);
            Map<String, Object> params = new HashMap();
            List<PlusTaskDTO> plusTaskDTOS = typpmPlanActiveService.queryPlanActiveTreeByPlanOidAndOtype(rootPlanId,TableTypeConstrant.TY_PLAN_OTYPE,params);
            StringBuilder stringBuilder=new StringBuilder();
            stringBuilder.append("修改计划时间:");
            for (PlusTaskDTO oaPlanVO:plusTaskDTOS){
                callBack(jsonArray,oaPlanVO,stringBuilder);
            }
            jo.put("field0032",stringBuilder);
            data.put("formson_15443",jsonArray);
        }else {
            throw new RuntimeException("错误的变更类型");
        }
        //申请人
        jo.put("field0010","-8801123846170458436");
        //编制日期
        jo.put("field0008",LocalDateTime.now());
        //项目名称
        jo.put("field0003",typpmProject.getName());

        data.put("templeteNumber","ty777");
        data.put("loginName","22051030");
        List<MIBAVO> mibavos = rtTaskMapper.selectIBAById(projectId);
        //开发等级
        Optional<MIBAVO> grade = mibavos.stream().filter(f -> f.getAttributeenname().equals("DevelopmentLevel")).findAny();
        grade.ifPresent(mibavo -> jo.put("field0009", mibavo.getAttributevalue()));
        //开发令
        Optional<MIBAVO> developmentOrder = mibavos.stream().filter(f -> f.getAttributeenname().equals("ProjectDevelopmentOrder")).findAny();
        developmentOrder.ifPresent(mibavo -> jo.put("field0004", mibavo.getAttributevalue()));
        jo.put("field0008", LocalDateTime.now());
        data.put("formmain_15442",jo);

        String str = data.toJSONString();
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, str);
        Request request = new Request.Builder()
                .url(this.url)
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .build();
        try {
            Response response = client.newCall(request).execute();
            String json = response.body().string();
            if(StrUtil.isNotBlank(json)){
                JSONObject jsonObject = JSONObject.parseObject(json);
                if (jsonObject.getString("success").equals("true")){
                    return jsonObject.getString("url");
                }
            }

            return null;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }



    public void callBack(JSONArray jsonArray,PlusTaskDTO oaPlanVO,StringBuilder stringBuilder){
        JSONObject jx = new JSONObject();
        //基准版计划名称
        jx.put("field0045",oaPlanVO.getName());
        //被比较版本计划名称
        jx.put("field0046",oaPlanVO.getName());
        //基准版计划开始时间
        jx.put("field0043",oaPlanVO.getStartDate());
        //基准版计划完成时间
        jx.put("field0044",oaPlanVO.getFinishDate());
        //被比较版本计划开始时间
        jx.put("field0041",oaPlanVO.getStartDate());
        //被比较版本计划完成时间
        jx.put("field0042",oaPlanVO.getFinishDate());
        stringBuilder.append(oaPlanVO.getOid()).append(",");
        jsonArray.add(jx);

        if (oaPlanVO.getChildren()!=null){
            List<PlusTaskDTO> children = oaPlanVO.getChildren();
            for (PlusTaskDTO child:children){
                callBack(jsonArray,child,stringBuilder);
            }
        }
    }

    @Override
    public String getProjectIdByName(String projectName) {
        return rtTaskMapper.getProjectIdByName(projectName);
    }

    @Override
    public List<TyJobVO> obtainTheProjectTaskId(String pjOid) {
        return rtTaskMapper.obtainTheProjectTaskId(pjOid);
    }

    @Override
    public void updateProjectJobTime(OAProjectJobDTO p) {
        rtTaskMapper.updateProjectJobTime(p);
    }

    @Override
    @Transactional(
            rollbackFor = Exception.class
    )
    public String changePlan1(ProjectPlanChangeDTO dto) {
        try {
            String projectOid = dto.getParams().getProjectoid();
            JSONObject data = new JSONObject();
            List<MIBAVO> mibavos = rtTaskMapper.selectIBAById(projectOid);

            StringBuilder changeObj = new StringBuilder();
            Map<String, JSONObject> activeChangeDetail = dto.getParams().getActiveList().stream().collect(
                    Collectors.toMap(ActiveUpdateVO::getOid, ActiveUpdateVO::getActiveDetail));
            if (CollUtil.isEmpty(activeChangeDetail)) {
                throw new RuntimeException("变更的计划不能为空!");
            }
            JSONArray array = dto.getParams().getPlanActiveDTO().getJSONArray("data");
            Map<String, JSONObject> sourcePlanMap = new HashMap<>();
            for (int i = 0; i < array.size(); i++) {
                JSONObject jsonObject = array.getJSONObject(i);
                sourcePlanMap.put(jsonObject.getString("UID"), jsonObject);
            }
            String key = snowflakeIdComponent.getInstance().nextId().toString();
            changeObj.append("对象:" + key);
            JSONArray changePlanArray = new JSONArray();
            dealProjectPlanArray(activeChangeDetail, sourcePlanMap, changeObj, changePlanArray);
            redisUtils.set(key, JSONObject.toJSONString(activeChangeDetail));

            TyppmProject typpmProject = typpmProjectService.selectOneByOID(projectOid);
            //创建变更单
            JSONObject jo = new JSONObject();
            PlanChangeInfoVO params = dto.getParams();
            if (ObjectUtil.isNotNull(params)) {
                jo.put("field0031", dto.getChangeReason());
                jo.put("field0005", params.getChangeNo());
            }

            //项目组长
            List<String> leaders = rtProjectMapper.selectProjectLeaderByProjectChgId(
                    dto.getParams().getChangeInfoOid());
            if (CollUtil.isNotEmpty(leaders)) {
                jo.put("field0002", leaders.get(0));
            } else {
                jo.put("field0002", TyAccountContext.getUser().getFullname());
            }
            jo.put("field0003", typpmProject.getName());
            jo.put("field0004", dto.getDevOrder());
            jo.put("field0011", "1");
            jo.put("field0032", changeObj);

            jo.put("field0061", "728686633171304449");
            jo.put("field0008", LocalDateTime.now());

            jo.put("field0009", dto.getDevelopmentLevel());
            jo.put("field0010", TyAccountContext.getUser().getFullname()); // 申请人

            //开发等级
            Optional<MIBAVO> grade = mibavos.stream().filter(f -> f.getAttributeenname().equals("DevelopmentLevel")).findFirst();
            grade.ifPresent(mibavo -> jo.put("field0009", mibavo.getAttributevalue()));
            //开发令
            Optional<MIBAVO> developmentOrder = mibavos.stream().filter(f -> f.getAttributeenname().equals("ProjectDevelopmentOrder")).findFirst();
            developmentOrder.ifPresent(mibavo -> jo.put("field0004", mibavo.getAttributevalue()));

            String code = "WT" + System.currentTimeMillis();
            jo.put("field0061", code);
            jo.put("field0066", projectOid);
            data.put("templeteNumber", "ty777");
            data.put("loginName", "22051030");
            data.put("formmain_15442", jo); // 主表
            data.put("formson_15443", changePlanArray); // 子表
            String oaFormDateUrl = projectChangeService.sentRequestToOa(data.toJSONString(), url);
            if(StringUtils.isBlank(oaFormDateUrl)){
                throw RTErrorCodeEnum.PROJECT_PARAMETER_NOT_EXIST.getException("OA项目变更表单创建失败");
            }

            projectChangeService.startWorkFlow(dto.getParams().getChangeInfoOid(), projectOid, code);
            return oaFormDateUrl;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    public void dealProjectPlanArray(Map<String, JSONObject> activeChangeDetail, Map<String, JSONObject> sourcePlanMap, StringBuilder stringBuilder,JSONArray result){
        stringBuilder.append("新增项目计划:{");
        for (Map.Entry<String, JSONObject> entry : activeChangeDetail.entrySet()) {
            JSONObject activeDetail = entry.getValue();
            stringBuilder.append(activeDetail.getString("oid")).append(",");
            HashMap<String, List> ibaMap = new HashMap<>();
            ibaMap.put("ExecutionStatus", Arrays.asList("正常"));
            activeDetail.put("ibaAttribute", ibaMap);
            JSONObject jx = new JSONObject();
            //基准版计划名称
            jx.put("field0045", activeDetail.getString("name")); //阶段计划名称
            //基准版计划完成时间
            String sourceFinishDate = activeDetail.getString("finishDate");
            String currentFinishDate = "";
            jx.put("field0064", sourceFinishDate);//
            //被比较版本计划完成时间
            if (sourcePlanMap.containsKey(entry.getKey())) {
                currentFinishDate = sourcePlanMap.get(entry.getKey()).getString("finishDate");
                jx.put("field0065", currentFinishDate);
            }
            if(StringUtil.isNotBlank(currentFinishDate) && StringUtil.isNotBlank(sourceFinishDate)){
                LocalDate sourceDate = LocalDate.parse(sourceFinishDate);
                LocalDate currentDate = LocalDate.parse(currentFinishDate);
                long daysDiff = ChronoUnit.DAYS.between(currentDate, sourceDate);
                jx.put("field0049", daysDiff);
            }
            result.add(jx);
        }
        stringBuilder.append("}");
    }


    public void updateExecutionStatus(String projectId,String type){
        if (projectId!=null&&projectId!=""){
            BigInteger projectOid = new BigInteger(projectId);
            BigInteger executionStatusId = rtTaskMapper.selectExecutionStatus("执行状态");
            if (type.equals("项目暂停")){
                rtTaskMapper.updateExecutionStatus("暂停",projectOid,executionStatusId);
            }
            if (type.equals("项目恢复")){
                rtTaskMapper.updateExecutionStatus("正常",projectOid,executionStatusId);
                List<BigInteger> JobList = rtTaskMapper.selectJobIdByProjectId(projectOid);
                for (BigInteger jobId : JobList) {
                    rtTaskMapper.updateExecutionStatus("正常",jobId,executionStatusId);
                }
            }
        }
    }

    @Override
    public void updatePlanDate(List<RTPlanUpdateDTO> rtPlanUpdateDTOS) throws SQLException {

        if (CollUtil.isEmpty(rtPlanUpdateDTOS)){
            return;
        }

        String rootPlanId=rtTaskMapper.selectRootPlanIdByPlanId(rtPlanUpdateDTOS.get(0).getPlanId());

        List<PlusTaskSaveDTO> plusTaskSaveDTOS = new ArrayList<>();

        Map<String, Object> params = new HashMap();
        List<PlusTaskDTO> historyPlanList = typpmPlanActiveService.queryPlanActiveTreeByPlanOidAndOtype(rootPlanId, TableTypeConstrant.TY_PLAN_OTYPE, params);

        List<PlusTaskDTO> ls=new ArrayList<>();
        for (PlusTaskDTO plusTaskDTO : historyPlanList) {
            callBack2(ls,plusTaskDTO);
        }


        Map<String, PlusTaskDTO> historyPlanMap = ls.stream()
                .collect(Collectors.toMap(
                        PlusTaskDTO::getName,  // 假设名称是唯一标识
                        plan -> plan,
                        (existing, replacement) -> existing  // 名称重复时保留第一个（按业务处理）
                ));
        for (String key : historyPlanMap.keySet()) {
            PlusTaskDTO plusTaskDTO = historyPlanMap.get(key);
            PlusTaskSaveDTO plusTaskSaveDTO = new PlusTaskSaveDTO();
            BeanUtil.copyProperties(plusTaskDTO, plusTaskSaveDTO);

            //计算工期
            plusTaskSaveDTO.setOutLineLevel(plusTaskDTO.getOutLineLevel().toString());
            plusTaskSaveDTO.setOutLineNumber(plusTaskDTO.getOutLineNumber());
            plusTaskSaveDTO.setLineNumber(plusTaskSaveDTO.getLineNumber());// 设置序号

            Optional<RTPlanUpdateDTO> any = rtPlanUpdateDTOS.stream().filter(
                    f -> f.getPlanId().equals(plusTaskDTO.getOid())).findAny();
            if (any.isPresent()){
                RTPlanUpdateDTO rtPlanUpdateDTO = any.get();
                LocalDateTime currentStartTime= rtPlanUpdateDTO.getStartDate();
                LocalDateTime currentEndTime= rtPlanUpdateDTO.getFinishDate();
                long durationMillis = WorkdayCalculator.calculateWorkdayDuration(
                        currentStartTime,
                        currentEndTime
                );
                String currentStartTimeFormat = currentStartTime.format(RTPlmConstant.DATETIME_FORMATTER);
                String currentEndTimeFormat = currentEndTime.format(RTPlmConstant.DATETIME_FORMATTER);
                plusTaskSaveDTO.setEarlyStart(currentStartTimeFormat);
                plusTaskSaveDTO.setConstraintDate(currentStartTimeFormat);
                plusTaskSaveDTO.setStartDate(currentStartTimeFormat);
                plusTaskSaveDTO.setLateStart(currentStartTimeFormat);
                plusTaskSaveDTO.setDuration(String.valueOf(durationMillis));
                plusTaskSaveDTO.setEarlyFinish(currentEndTimeFormat); // 设置结束时间
                plusTaskSaveDTO.setFinishDate(currentEndTimeFormat); // 设置结束时间
                plusTaskSaveDTO.setLateFinish(currentEndTimeFormat);
            }else {
                String currentStartTimeFormat = plusTaskDTO.getStartDate().format(RTPlmConstant.DATETIME_FORMATTER);
                String currentEndTimeFormat = plusTaskDTO.getFinishDate().format(RTPlmConstant.DATETIME_FORMATTER);
                plusTaskSaveDTO.setEarlyStart(currentStartTimeFormat);
                plusTaskSaveDTO.setConstraintDate(currentStartTimeFormat);
                plusTaskSaveDTO.setStartDate(currentStartTimeFormat);
                plusTaskSaveDTO.setLateStart(currentStartTimeFormat);
//                plusTaskSaveDTO.setDuration(String.valueOf(durationMillis));
                plusTaskSaveDTO.setEarlyFinish(currentEndTimeFormat); // 设置结束时间
                plusTaskSaveDTO.setFinishDate(currentEndTimeFormat); // 设置结束时间
                plusTaskSaveDTO.setLateFinish(currentEndTimeFormat);
            }


            if (plusTaskDTO.getActualFinishDate()!=null){
                plusTaskSaveDTO.setActualFinishDate(plusTaskDTO.getActualFinishDate().format(RTPlmConstant.DATETIME_FORMATTER));
            }
            if (plusTaskDTO.getActualStartDate()!=null){
                plusTaskSaveDTO.setActualStartDate(plusTaskDTO.getActualStartDate().format(RTPlmConstant.DATETIME_FORMATTER));
            }
            if (StrUtil.isBlank(plusTaskSaveDTO.getControlled())){
                plusTaskSaveDTO.setControlled("false");
            }
            if (StrUtil.isNotBlank(plusTaskSaveDTO.getRiskType()) && !RISK_TYPE_LIST.contains(plusTaskSaveDTO.getRiskType())){
                String riskType = plusTaskSaveDTO.getRiskType();
                switch (riskType) {
                    case "不可用":
                        plusTaskSaveDTO.setRiskType("UNAVAILABLE");
                        break;
                    case "很低":
                        plusTaskSaveDTO.setRiskType("Very low");
                        break;
                    case "很高":
                    case "极高":
                        plusTaskSaveDTO.setRiskType("Very high");
                        break;
                    case "中":
                        plusTaskSaveDTO.setRiskType("Medium");
                        break;
                    case "高":
                        plusTaskSaveDTO.setRiskType("High");
                        break;
                    case "低":
                        plusTaskSaveDTO.setRiskType("Low");
                        break;
                }
            }
            plusTaskSaveDTOS.add(plusTaskSaveDTO);
        }

//        for (RTPlanUpdateDTO rtPlanUpdateDTO : rtPlanUpdateDTOS) {
//            if (!historyPlanMap.containsKey(rtPlanUpdateDTO.getName())){
//                continue;
//            }
//
//            PlusTaskSaveDTO plusTaskSaveDTO = new PlusTaskSaveDTO();
//
//            String planId =rtPlanUpdateDTO.getPlanId();
//
//            LocalDateTime startDate=rtPlanUpdateDTO.getStartDate();
//
//            LocalDateTime finishDate=rtPlanUpdateDTO.getFinishDate();
//
//            TyppmPlanActive typpmPlanActive = typpmPlanActiveService.selectOneByOID(planId);
//
//            BeanUtil.copyProperties(typpmPlanActive,plusTaskSaveDTO);
//
//            plusTaskSaveDTO.setStartDate(adjustToNextWorkday(startDate).format(formatter));
//
//            plusTaskSaveDTO.setFinishDate(adjustToNextWorkday(finishDate).format(formatter));
//
//            plusTaskSaveDTO.setMilestone(plusTaskSaveDTO.getMilestone().equals("true")?"1":"0");
//
//            plusTaskSaveDTO.setCritical(plusTaskSaveDTO.getCritical().equals("true")?"1":"0");
//
//            plusTaskSaveDTO.setCritical(plusTaskSaveDTO.getCritical().equals("true")?"1":"0");
//
//            plusTaskSaveDTO.setSummary(plusTaskSaveDTO.getSummary().equals("true")?"1":"0");
//
//            plusTaskSaveDTO.setEffortDriven(plusTaskSaveDTO.getEffortDriven().equals("true")?"1":"0");
//
//            plusTaskSaveDTO.setControlled(plusTaskSaveDTO.getControlled().equals("true")?"1":"0");
//
//            if (StrUtil.isNotBlank(plusTaskSaveDTO.getEarlyStart())){
//                plusTaskSaveDTO.setEarlyStart(convertDateTimeFormat(plusTaskSaveDTO.getEarlyStart()));
//            }
//
//            if (StrUtil.isNotBlank(plusTaskSaveDTO.getEarlyFinish())){
//                plusTaskSaveDTO.setEarlyFinish(convertDateTimeFormat(plusTaskSaveDTO.getEarlyFinish()));
//            }
//
//            if (StrUtil.isNotBlank(plusTaskSaveDTO.getLateStart())){
//                plusTaskSaveDTO.setLateStart(convertDateTimeFormat(plusTaskSaveDTO.getLateStart()));
//            }
//
//            if (StrUtil.isNotBlank(plusTaskSaveDTO.getLateFinish())){
//                plusTaskSaveDTO.setLateFinish(convertDateTimeFormat(plusTaskSaveDTO.getLateFinish()));
//            }
//
//
////            plusTaskSaveDTO.setShowinTimeLine(plusTaskSaveDTO.getShowinTimeLine().equals("true")?"1":"0");
//
//            plusTaskSaveDTOS.add(plusTaskSaveDTO);
//        }


//        BatchLockParams batchLockParams = new BatchLockParams();
//        PlanActiveLockDTO planActiveLockDTO = new PlanActiveLockDTO();
//        planActiveLockDTO.setOid(rootPlanId);
//        planActiveLockDTO.setOtype("ty.projectmng.admin.CTyPlan");
//        batchLockParams.setPlan(planActiveLockDTO);


        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Map<String, TIMESTAMP> map=rtProjectMapper.selectPlanTimeById(rootPlanId.toString());
        //获取最早时间
        String startDate = plusTaskSaveDTOS.stream().min((t1, t2) -> {
            try {
                return sdf.parse(t1.getStartDate()).compareTo(sdf.parse(t2.getStartDate()));
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }).get().getStartDate();
        //获取最晚时间
        String finishDate = plusTaskSaveDTOS.stream().max((t1, t2) -> {
            try {
                return sdf.parse(t1.getFinishDate()).compareTo(sdf.parse(t2.getFinishDate()));
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }).get().getFinishDate();
        PlanTime planTime=new PlanTime();
        planTime.setOid(rootPlanId);
        if (Timestamp.valueOf(startDate).compareTo(map.get("STARTDATE").timestampValue())<0){
            planTime.setStartTime(startDate);
        }else if (Timestamp.valueOf(startDate).compareTo(map.get("STARTDATE").timestampValue())==0){
            planTime.setStartTime(startDate.substring(0,10)+" 00:00:00");
        }

        if (Timestamp.valueOf(finishDate).compareTo(map.get("FINISHDATE").timestampValue())>0){
            planTime.setEndTime(finishDate);
        }else if (Timestamp.valueOf(finishDate).compareTo(map.get("FINISHDATE").timestampValue())==0){
            planTime.setEndTime(finishDate.substring(0,10)+" 23:59:59");
        }
        if (!(StrUtil.isBlank(planTime.getStartTime()) && StrUtil.isBlank(planTime.getEndTime()))){
            rtProjectMapper.updatePlanTime(planTime);
        }
//        planActiveService.lockAllPlanActive(batchLockParams);
        ganttChartService.saveTableTreeEx(rootPlanId, plusTaskSaveDTOS);

    }

    @Override
    public void updatePlanActivity(String key,String projectId) {
        String json = redisUtils.get(key);
        JSONArray jsonArray = JSONObject.parseArray(json);
//        List<PlusTaskSaveDTO> javaList = jsonArray.toJavaList(PlusTaskSaveDTO.class);
        List<PlusTaskSaveDTO> javaList = jsonArray.toJavaList(PlusTaskSaveDTO.class);
        String planId=rtTaskMapper.selectPlanIdByProjectId(projectId);
        int i=0;
        for (PlusTaskSaveDTO plusTaskSaveDTO : javaList) {
            String startDate = plusTaskSaveDTO.getStartDate();
            if (startDate.contains("T")){
                startDate=convertToLocalDateTime(startDate);
            }
            String finishDate = plusTaskSaveDTO.getFinishDate();
            if (finishDate.contains("T")){
                finishDate=convertToLocalDateTime(finishDate);
            }
            plusTaskSaveDTO.setEarlyStart(startDate);
            plusTaskSaveDTO.setEarlyFinish(finishDate);
            plusTaskSaveDTO.setLateFinish(finishDate);
            plusTaskSaveDTO.setLateStart(startDate);
            plusTaskSaveDTO.setStartDate(startDate);
            plusTaskSaveDTO.setFinishDate(finishDate);
            plusTaskSaveDTO.setControlled("0");
            if (jsonArray.getJSONObject(i).containsKey("oid")){
                String oid = jsonArray.getJSONObject(i).getString("oid");
                if (NumberUtil.isNumber(oid)){
                    plusTaskSaveDTO.setOid(oid);
                }else {
                    String actId=rtTaskMapper.selectActivityByName(plusTaskSaveDTO.getName(),plusTaskSaveDTO.getOutLineNumber(),plusTaskSaveDTO.getOutLineLevel(),planId);

                    if (StrUtil.isNotBlank(actId)){
                        TyppmPlanActive typpmPlanActive = typpmPlanActiveService.selectOneByOID(actId);
                        plusTaskSaveDTO.setOid(actId);
                        plusTaskSaveDTO.setLineNumber(typpmPlanActive.getLineNumber().toString());
                    }else {
                        plusTaskSaveDTO.setOid(snowflakeIdComponent.getInstance().nextId().toString());
                    }
                }

            }
            if (StrUtil.isNotBlank(plusTaskSaveDTO.getParentOID()) && plusTaskSaveDTO.getParentOID().equals("-1")){
                if (plusTaskSaveDTO.getParentOTYPE().equals("ty.projectmng.admin.CTyPlan")){
                    plusTaskSaveDTO.setParentOID(planId);
                }else {
                    plusTaskSaveDTO.setParentOID(jsonArray.getJSONObject(i).getString("parentId"));
                }
            }
            if (!NumberUtil.isLong(plusTaskSaveDTO.getDuration())){
                plusTaskSaveDTO.setDuration(plusTaskSaveDTO.getDuration().substring(0,1));
            }
            if (plusTaskSaveDTO.getIbaAttribute().containsKey("ActualDuration")){
                plusTaskSaveDTO.getIbaAttribute().remove("ActualDuration");
            }
            if (plusTaskSaveDTO.getIbaAttribute().containsKey("ActualStart")){
                plusTaskSaveDTO.getIbaAttribute().remove("ActualStart");
            }
            if (plusTaskSaveDTO.getIbaAttribute().containsKey("ActualFinish")){
                plusTaskSaveDTO.getIbaAttribute().remove("ActualFinish");
            }
            plusTaskSaveDTO.setLockStatus("1");
            plusTaskSaveDTO.setLockUserOid("105");
            plusTaskSaveDTO.setControlled("0");
            plusTaskSaveDTO.setCritical("1");


            if (StrUtil.isBlank(plusTaskSaveDTO.getLineNumber())){
                plusTaskSaveDTO.setLineNumber("1");
            }
            i++;
        }

        ArrayList<PlusTaskSaveDTO> collected = javaList.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(PlusTaskSaveDTO::getOid))),
                ArrayList::new));

        ganttChartService.saveTableTreeEx(planId,collected);
    }

    public static String convertToLocalDateTime(String isoDateTime) {
        Instant instant = Instant.parse(isoDateTime);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
                .withZone(ZoneId.systemDefault()); // 使用系统默认时区

        return formatter.format(instant);
    }

    private void callBack2(List<PlusTaskDTO> ls, PlusTaskDTO plusTaskDTO) {

        ls.add(plusTaskDTO);

        if (CollUtil.isEmpty(plusTaskDTO.getChildren())){
            return;
        }

        for (PlusTaskDTO child : plusTaskDTO.getChildren()) {
            callBack2(ls,child);
        }
    }

    // 将日期调整为下一个工作日（如果当前是周末）
    public LocalDateTime adjustToNextWorkday(LocalDateTime date) {
        DayOfWeek day = date.getDayOfWeek();
        if (day == DayOfWeek.SATURDAY) {
            return date.plusDays(2); // 周六 → 周一
        } else if (day == DayOfWeek.SUNDAY) {
            return date.plusDays(1); // 周日 → 周一
        }
        return date; // 工作日不调整

    }

    public static String convertDateTimeFormat(String inputDateStr) {
        try {
            // 解析输入日期
            SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm");
            Date date = inputFormat.parse(inputDateStr);

            // 设置为当天的23:59:59
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);

            // 格式化输出
            SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return outputFormat.format(calendar.getTime());
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
